const int IR_LED = 2;
const int Freq = 38000;
const int CarrierCyclesInOneBaud = 24;

//发送一次载波
//发送数据0则发送数据，接收器总线将被拉低
//发送数据1则不发送数据，接收器总线保持高电平
void IRSendCarrier(unsigned char  dat){
  if(dat){
    for(int i = 0;i < CarrierCyclesInOneBaud;i++)
    { // 发送数据1，接收器不拉低
      digitalWrite(IR_LED, 0);
      delayMicroseconds(13);
      digitalWrite(IR_LED, 0);
      delayMicroseconds(13);
    }
  }
  else
  {
    for(int i = 0;i < CarrierCyclesInOneBaud;i++)
    {
      // 发送数据0，接收器总线拉低
      digitalWrite(IR_LED, 1);
      delayMicroseconds(13);
      digitalWrite(IR_LED, 0);
      delayMicroseconds(13);
    }
  }
}

void IRSendByte(unsigned char dat){
  // 8个数据位，无校验位，1个停止位，低字节优先发送
  // 发送一个起始位
  IRSendCarrier(0);
  for(int i = 0x01;i&0xff;i<<=1)
  {
    IRSendCarrier(i & dat);
  }
  //发送停止位
  IRSendCarrier(0);

  delay(40);
}

/*
 * 报头脉冲：9ms
 * 报头间距：4.5ms
 * 载波频率：37.9KHz（38KHz）
 * 码段1与码段2间距：20ms
 * “1”：脉宽，656us。间距，1640us。
 * “0”：脉宽，656us。间距，544us。
 */

void ACSendBit(byte dat)
{
  //脉宽，656us。
  for(int i = 0;i<25;i++)
  {
    digitalWrite(IR_LED, 1);
    delayMicroseconds(13);
    digitalWrite(IR_LED, 0);
    delayMicroseconds(13);
  }
  if(dat)
  {
    //“1”：脉宽，656us。间距，1640us。
    delayMicroseconds(1640);
  }else
  {
    //“0”：脉宽，656us。间距，544us。
    delayMicroseconds(544);
  }
}

// 发送报头脉冲和报头间距
void ACSendHeader()
{
  // 报头脉冲：9ms
  for(int i = 0; i<342; i++)
  {
    digitalWrite(IR_LED, 1);
    delayMicroseconds(13);
    digitalWrite(IR_LED, 0);
    delayMicroseconds(13);
  }
  // 报头间距：4.5ms
  delayMicroseconds(4500);
}

void ACSendCommand()
{
  // 读取10个字节到内存中
  unsigned char commands[10];
  for(int i = 0;i < 10; i++)
  {
    while(!Serial.available());
    commands[i] = (unsigned char)Serial.read();
    // Serial.print(commands[i]);
  }
  // Serial.println();
  // 报头脉冲：9ms + 报头间距：4.5ms
  ACSendHeader();
  for(int i = 0; i < 36;i++)
  {
    ACSendBit(commands[i/8] & (0x01 << (i % 8)));
  }
  //码段1与码段2间距：20ms
  delay(20);
  
  for(int i = 0; i< 33;i++)
  {
    ACSendBit(commands[(i/8)+5] & (0x01 << (i % 8)));
  }
}

void setup() {
  pinMode(IR_LED, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  while(!Serial.available());
  unsigned char  recv = Serial.read();
  if(recv == 0x05)
  {
    ACSendCommand();
  }
  else
  {
    IRSendByte(recv);
    Serial.write(recv);
  }
}
